/*****************************************************************************/
/*                                                                           */
/*    Domino Operation System Driver Module                                  */
/*                                                                           */
/*    Copyright (C) 2011 Laszlo Arvai                                        */
/*                                                                           */
/*    ------------------------------------------------------------------     */
/*    MRF49XA driver                                                         */
/*****************************************************************************/

#ifndef __drvMRF49XA_h
#define __drvMRF49XA_h

///////////////////////////////////////////////////////////////////////////////
// Includes
#include <krnlTypes.h>

///////////////////////////////////////////////////////////////////////////////
// Constants

/*******************************************************************************
 * Bit definitions for MRF registers
 *
 * These defines are provided for use configuring the MRF49XA module.  The
 * register address is the first define in each section, and must be written
 * to the MOSI pins to access the register.
 *
 * To set register states, bit-wise or the address with the desired set bits
 * for the register.
 *
 * To read the register states, you must also write to any bits that are R/W
 * Luckily, the only register worth reading is STSREG, and has no settable bits
 * 
 * Some registers contain values that need to be derived, or select a range of
 * settings.  Each of these has their own section containing the equation
 * and/or individual defines for each setting.
 *
 ******************************************************************************/
#define drvMRF_STSREG				0x0000		// Status read register address
#define drvMRF_TXRXFIFO			0x8000		// FIFO state (1 = ready)
#define drvMRF_POR					0x4000		// Power-on-Reset flag
#define drvMRF_TXOWRXOF			0x2000		// Underrun/Overwrite/Overflow
#define drvMRF_WUTINT				0x1000		// Wakeup timer overflow interrupt
#define drvMRF_LCEXINT			0x0800		// Logic change interrupt
#define drvMRF_LBTD					0x0400		// Low Battery threshold detect
#define drvMRF_FIFOEM				0x0200		// Receiver FIFO empty (1 = empty)
#define drvMRF_ATTRSSI			0x0100		// Antenna Tuning and RSSI indicator
#define drvMRF_DQDO					0x0080		// Data Quality Detect/Indicate output
#define drvMRF_CLKRL				0x0040		// Clock recovery lock bit
#define drvMRF_AFCCT				0x0020		// Automatic frequency control cycle toggle
#define	drvMRF_OFFSV				0x0010		// Measured frequency offset of AFC cycle
#define drvMRF_OFFSET_MASK	0x000F		// Value of the AFC offset (see datasheet)

/*******************************************************************************
 * Convenience definitions for Automatic frequency control configuration reg.
 *
 * These defines are provided for use configuring the MRF49XA module.
 * 
 * The AutoMS field sets the mode, and ARFO sets the allowable tuning range.
 * The MFCS, HAM, FOREN, and FOFEN bits set the manual control strobe, high
 * accuracy mode, frequency offset register, and frequency offset respectively
 *
 ******************************************************************************/
#define drvMRF_AFCCREG			0xC400		// AFC configuration register address

// Automatic frequency mode selection
#define drvMRF_AUTOMS_INDP	0x00C0		// Offset independent for state of DIO sig.
#define drvMRF_AUTOMS_RECV	0x0080		// Offset only during receive
#define drvMRF_AUTOMS_ONCE	0x0040		// Offset once after power-cycle
#define drvMRF_AUTOMS_OFF		0x0000		// Auto mode off

// Allowable tuning range selection
#define drvMRF_ARFO_3to4		0x0030		// +3 to -4 Fres (tuning bits)
#define drvMRF_ARFO_7to8		0x0020		// +7 to -8 Fres
#define drvMRF_ARFO_15to16	0x0010		// +15 to -16 Fres
#define drvMRF_ARFO_unlim		0x0000		// Unlimited

// Other flags in automatic tuning set register
#define drvMRF_MFCS					0x0008		// Manual Frequency control strobe
#define drvMRF_HAM					0x0004		// High accuracy mode
#define drvMRF_FOREN				0x0002		// Frequency Offset Register Enable
#define drvMRF_FOFEN				0x0001		// Frequency Offset Enable

/*******************************************************************************
 * Convenience definitions for Transmit byte register
 * 
 * This register allows for filling the transmit register one byte at a time.
 * The top byte of the command is the address, the bottom byte is the data.
 ******************************************************************************/
#define drvMRF_TXBREG			0xB800		// Transmit byte register address
#define drvMRF_TXDB_MASK	0x00FF		// Transmit byte mask


#define drvMRF_BBFCREG		0xC228		// Baseband filter config. register address
#define drvMRF_ACRLC			0x0080		// Automatic clock recovery lock control
#define drvMRF_MCRLC			0x0040		// Manual clock recovery lock control
#define drvMRF_FTYPE			0x0010		// Filter type (0 = digital, 1 = Ext. RC)
#define drvMRF_DQTI_MASK	0x0007		// Data quality threshold indicator

#define drvMRF_RXFIFOREG	0xB000		// Receiver FIFO read register
#define drvMRF_RXDB_MASK	0x00FF		// Receive data byte mask

/*******************************************************************************
 * Convenience definitions for FIFO and Reset mode configuration register
 *
 * These defines are provided for use configuring the MRF49XA module.
 * 
 * The FFBC field of this register sets the number of bits to receive before
 * a FIFO full interrupt is generated.  A reasonable number is 8.  The maximum
 * is 15 bits.
 *
 ******************************************************************************/
#define drvMRF_FIFORSTREG	0xCA00		// FIFO/Reset mode configuration register
#define drvMRF_FFBC_MASK	0x00F0		// FIFO Fill Bit Count (maximum = 15)
#define drvMRF_SYCHLEN		0x0008		// Synchronous Character length
#define drvMRF_FFSC				0x0004		// FIFO Fill Start condition
#define drvMRF_FSCF				0x0002		// FIFO Synchronous Character fill
#define drvMRF_DRSTM			0x0001		// Disable (sensitive) reset mode

#define drvMRF_SYNBREG		0xCE00		// Synchrnous byte config. register address
#define drvMRF_SYNCB			0x00FF		// Sync byte configuration

#define drvMRF_PMCREG			0x8200		// Power Mgmt. Config. Register address
#define drvMRF_RXCEN			0x0080		// Receiver chain enable
#define drvMRF_BBCEN			0x0040		// Baseband chain enable
#define drvMRF_TXCEN			0x0020		// Transmitter chain enable
#define drvMRF_SYNEN			0x0010		// Synthesier enable
#define drvMRF_OSCEN			0x0008		// Oscillator enable
#define drvMRF_LBDEN			0x0004		// Low Battery Detector Enable
#define	drvMRF_WUTEN			0x0002		// Wakeup timer enable
#define drvMRF_CLKODIS		0x0001		// Clock output disable

#define drvMRF_WTSREG			0xE000		// Wakeup timer value register address
#define drvMRF_WTEV_MASK	0x1F00		// Wakeup timer exponential value
#define drvMRF_WTMV_MASK	0x00FF		// Wakeup timer multiplier exponential value

#define drvMRF_DCSREG			0xC800		// Duty cycle value set register
#define drvMRF_DCMV_MASK	0x00FE		// Duty cycle multiplier value mask
#define drvMRF_DCMEN			0x0001		// Duty cycle mode enable

#define drvMRF_CSREG			0xC000		// Battery thres. and clock set reg. address
#define drvMRF_COFSB_MASK	0x00E0		// Clock output frequency set
#define drvMRF_LBDVB_MASK	0x0008		// Low battery detect value

/*******************************************************************************
 * Convenience definitions for PLL Configuration register
 *
 * These defines are provided for use configuring the MRF49XA module.
 * 
 * The default setting is for 5-10 MHz output clock, Phase detector delay
 * disabled, PLL dithering disabled, and PLL bandwidth set to -102dBc/Hz
 * which is appropriate for higher bit rates.
 *
 * > 90kbps -> -102dBc/Hz (max 256kbps)
 * < 90kbps -> -107dBc/Hz (max 86.2kbps) 
 *
 ******************************************************************************/
#define drvMRF_PLLCREG		0xCC12		// PLL configuration register

// Clock buffer time control settings
#define drvMRF_CBTC_5p		0x0060		// Clock buffer 5-10 Mhz
#define drvMRF_CBTC_3			0x0040		// Clock buffer 3.3 Mhz
#define drvMRF_CBTC_2p		0x0020		// Clock buffer > 2.5 Mhz
#define drvMRF_CBTC_2m		0x0000		// Clock buffer < 2.5 Mhz

#define drvMRF_PDDS				0x0008		// Phase detector delay
#define drvMRF_PLLDD			0x0004		// PLL Dithering Disable
#define drvMRF_PLLBWB			0x0001		// PLL Bandwidth (102dBc/Hz)

/*******************************************************************************
 * Convenience definitions for band setting
 *
 * These defines are provided for use configuring the MRF49XA module.
 * Select the frequency band for the given hardware by uncommenting the
 * appropriate line.  Set the crystal load capactiance using the drvMRF_XTAL_LD_CAP
 * value.
 *
 * The load capactiance is given by the following equation:
 *
 * Cap pF = 8.5 + (LCS / 2)
 * LCS = (10 - 8.5) * 2
 *
 * For 10pF: LCS = (10 - 8.5) * 2 = 1.5 * 2 = 3
 * 
 ******************************************************************************/
#define drvMRF_GENCREG		0x8000		// General configuration register addres
#define drvMRF_TXDEN			0x0080		// TX Data Register enable bit
#define drvMRF_FIFOEN			0x0040		// FIFO enable bit
#define drvMRF_FBS_MASK		0x0030		// Mask for the band selection
#define drvMRF_LCS_MASK		0x000F		// Mask for the crystal load capactiance

// Crystal load capacitance
#define drvMRF_XTAL_LD_CAP_85         0x0000
#define drvMRF_XTAL_LD_CAP_9          0x0001
#define drvMRF_XTAL_LD_CAP_95         0x0002
#define drvMRF_XTAL_LD_CAP_10         0x0003
#define drvMRF_XTAL_LD_CAP_105        0x0004
#define drvMRF_XTAL_LD_CAP_11         0x0005
#define drvMRF_XTAL_LD_CAP_115        0x0006
#define drvMRF_XTAL_LD_CAP_12         0x0007
#define drvMRF_XTAL_LD_CAP_125        0x0008
#define drvMRF_XTAL_LD_CAP_13         0x0009
#define drvMRF_XTAL_LD_CAP_135        0x000A
#define drvMRF_XTAL_LD_CAP_14         0x000B
#define drvMRF_XTAL_LD_CAP_145        0x000C
#define drvMRF_XTAL_LD_CAP_15         0x000D
#define drvMRF_XTAL_LD_CAP_155        0x000E
#define drvMRF_XTAL_LD_CAP_16         0x000F 

// Frequency band settings
#define drvMRF_FBS_434		0x0010		// 434 mHz band
#define drvMRF_FBS_868		0x0020		// 868 mHz band
#define drvMRF_FBS_915		0x0030		// 915 mHz band

/*******************************************************************************
 * Convenience definitions for center frequency
 *
 * These defines are provided for use configuring the MRF49XA module.
 * Select the center frequency using the following equation:
 * 
 * Fo = 10 * FA1 * (FA0 + Fval/4000)
 * Fval = Decimal value of FREQB, 96 < Fval < 3903
 * 
 * Choose FA1 anf FA0 using the following table according to band:
 * 
 *		Range		FA1			FA0
 *		434			1			43
 *		868			2			43
 *		915			3			30
 *
 * Fo = 10 * (43 + Fval/4000) = 10*43 + 10*(Fval/4000) = 430 + Fval/400
 *
 * Fval = (Fo - 430) * 400 = (432.10 - 430) * 400 = 2.1 * 400 = 840
 * 
 ******************************************************************************/
#define drvMRF_CFSREG			0xA000		// Center Frequency value register address
#define drvMRF_FREQB_MASK	0x0FFF		// Center Frequency value (see datasheet)

/*******************************************************************************
 * Convenience definitions for receiver control register
 *
 * These defines are provided for use configuring the MRF49XA module.
 * It is possible to set the values for Data Integrity integration time,
 * Baseband bandwidth values, and LNA gain.
 *
 * Use the drvMRF_RXCREG_SET define for Microchip defaults
 * 
 ******************************************************************************/
#define drvMRF_RXCREG				0x9000		// Receive control register address
#define drvMRF_FINTDIO			0x0400		// Function interrupt/dio output
#define drvMRF_DIORT_MASK		0x0300		// Data indicator response time
#define drvMRF_RXBW_MASK		0x00E0		// Receiver baseband bandwidth
#define drvMRF_RXLNA_MASK		0x0018		// Receiver LNA gain
#define drvMRF_DRSSIT_MASK	0x0007		// Digital RSSI threshold

// Data indicator output response time
#define drvMRF_DIORT_CONT	0x0300		// Continuous
#define drvMRF_DIORT_SLOW	0x0200		// Slow
#define drvMRF_DIORT_MED	0x0100		// Medium
#define drvMRF_DIORT_FAST	0x0000		// Fast

// Receiver Baseband bandwidth
#define drvMRF_RXBW_67K		0x00C0		// Receiver Bandwidth 67 khz
#define drvMRF_RXBW_134K	0x00A0		// Receiver Bandwidth 134 khz
#define drvMRF_RXBW_200K	0x0080		// Receiver Bandwidth 200 khz
#define drvMRF_RXBW_270K	0x0060		// Receiver Bandwidth 270 khz
#define drvMRF_RXBW_340K	0x0040		// Receiver Bandwidth 340 khz
#define drvMRF_RXBW_400K	0x0020		// Receiver Bandwidth 400 khz

// Receiver LNA Gain
#define drvMRF_RXLNA_20DB	0x0018		// LNA Gain -20dB
#define drvMRF_RXLNA_14DB	0x0010		// LNA Gain -14dB
#define drvMRF_RXLNA_6DB	0x0008		// LNA Gain -6dB
#define drvMRF_RXLNA_0DB	0x0000		// LNA Gain  0dB

// Digital RSSI threshold
#define drvMRF_DRSSIT_73db	0x0005		// -73dB Threshold
#define drvMRF_DRSSIT_79db	0x0004		// -79dB Threshold
#define drvMRF_DRSSIT_85db	0x0003		// -85dB Threshold
#define drvMRF_DRSSIT_91db	0x0002		// -91dB Threshold
#define drvMRF_DRSSIT_97db	0x0001		// -97dB Threshold
#define drvMRF_DRSSIT_103db 0x0000		// -103dB Threshold

/*******************************************************************************
 * Convenience definitions for transmitter control register
 *
 * These defines are provided for use configuring the MRF49XA module.
 * Select the modulation bandwidth and output power by bit-wise oring them
 * with the register address.
 *
 * Use the drvMRF_TXCREG_SET for Microchip defaults
 * 
 ******************************************************************************/
#define drvMRF_TXCREG		0x9800		// Transmit configuration register address
#define drvMRF_MODPLY		0x0100		// Modulation polarity
#define drvMRF_MODBW_MASK	0x00F0		// Modulation bandwidth
#define drvMRF_OTXPWR_MASK 0x0007		// Output transmit power

// Modulation bandwidth settings
#define drvMRF_MODBW_240K	0x00F0		// 240kHz modulation bandwidth
#define drvMRF_MODBW_225K	0x00E0		// 240kHz modulation bandwidth
#define drvMRF_MODBW_210K	0x00D0		// 240kHz modulation bandwidth
#define drvMRF_MODBW_195K	0x00C0		// 240kHz modulation bandwidth
#define drvMRF_MODBW_180K	0x00B0		// 240kHz modulation bandwidth
#define drvMRF_MODBW_165K	0x00A0		// 240kHz modulation bandwidth
#define drvMRF_MODBW_150K	0x0090		// 240kHz modulation bandwidth
#define drvMRF_MODBW_135K	0x0080		// 240kHz modulation bandwidth
#define drvMRF_MODBW_120K	0x0070		// 240kHz modulation bandwidth
#define drvMRF_MODBW_105K	0x0060		// 240kHz modulation bandwidth
#define drvMRF_MODBW_90K	0x0050		// 240kHz modulation bandwidth
#define drvMRF_MODBW_75K	0x0040		// 240kHz modulation bandwidth
#define drvMRF_MODBW_60K	0x0030		// 240kHz modulation bandwidth
#define drvMRF_MODBW_45K	0x0020		// 240kHz modulation bandwidth
#define drvMRF_MODBW_30K	0x0010		// 240kHz modulation bandwidth
#define drvMRF_MODBW_15K	0x0000		// 240kHz modulation bandwidth

// Output power settings
#define drvMRF_OTXPWR_17D5	0x0007		// -17.5dB Transmit Output Power
#define drvMRF_OTXPWR_15D0	0x0006		// -15.0dB Transmit Output Power
#define drvMRF_OTXPWR_12D5	0x0005		// -12.5dB Transmit Output Power
#define drvMRF_OTXPWR_10D5	0x0004		// -10.5dB Transmit Output Power
#define drvMRF_OTXPWR_7D5	0x0003		// -7.5dB Transmit Output Power
#define drvMRF_OTXPWR_5D0	0x0002		// -5.0dB Transmit Output Power
#define drvMRF_OTXPWR_2D5	0x0001		// -2.5dB Transmit Output Power
#define drvMRF_OTXPWR_0	0x0000		//  0dB Transmit Output Power

/*******************************************************************************
 * Convenience definitions for data rate value set register
 *
 * These defines are provided for use configuring the MRF49XA module.
 * 
 * To calculate the DRPV value using the following equation:
 *
 * DRPV = 10000/[29 * (1 + DPRE * 7) * DREx] - 1 
 *
 * Where DPRE is either 1 or 0, and DREx is the desired data rate (kbps)
 *
 * 10000/[29 * 1 * 9.6] - 1 = 10000/278.4 - 1 = 35.9 - 1 = 34.9 = 35
 * 
 ******************************************************************************/
#define drvMRF_DRSREG		0xC600		// Data rate value set register address
#define drvMRF_DRPE		0x0080		// Data rate prescaler enable
#define drvMRF_DRPV_MASK	0x007F		// Data rate value mask

// Settings for approx. 9600 baud
#define drvMRF_DRPE_ENABLE	0x0080		// Data rate prescaler enable bit
#define drvMRF_DRPV_VALUE	35			// Derived value for 9579 baud


/*******************************************************************************
 * This section of the header file includes the interface used by the user
 * application.  This includes an initialization routine, and functions to set
 * desired center frequency, baud rate, deviation, etc.
 *
 * In addition to initialization an configuration functions, functions are
 * provided for sending a packet, as well as receiving one.
 *
 ******************************************************************************/

// Packet structures
#define drvMRF_PAYLOAD_LEN 40			// the maximum payload size
// Space for preamble, sync, length and dummy
#define drvMRF_TX_PACKET_LEN	drvMRF_PAYLOAD_LEN + 5	

typedef struct
{
	dosByte	length;
	dosByte payload[drvMRF_PAYLOAD_LEN];
} drvMRFPacket;

// setup functions
void drvMRFInit(void);
//void drvMRF_set_baud(dosWord baud);	// Sets the baud rate in kbps
void drvMRFReset(void);

// status functions
dosByte drvMRFIsIdle();

// Packet transmit functions
dosBool drvMRFTransmitPacket(drvMRFPacket *packet);

// Packet receive functions
drvMRFPacket* drvMRFGetReceivedPacket();

// Other functions
void drvMRFInterruptHandler(void);

// Testing functions
#ifdef drvMRF_TEST_MODE
void drvMRFTransmitZero(void);
void drvMRFTransmitOne(void);
void drvMRFTransmitAlternating(void);
#endif

#endif
